#include "../include/header.h"


// 设置文件类型和权限字符串
void set_type_mode(mode_t mode, char* str) {
    // 根据文件类型设置字符串的第一个字符
    switch (mode & S_IFMT) {
        case S_IFBLK:  
			str[0] = 'b'; 
			break; // 块设备
        case S_IFCHR:  
			str[0] = 'c'; 
			break; // 字符设备
        case S_IFDIR:  
			str[0] = 'd'; 
			break; // 目录
        case S_IFIFO:  
			str[0] = 'p'; 
			break; // 管道
        case S_IFLNK:  
			str[0] = 'l'; 
			break; // 链接
        case S_IFREG:  
			str[0] = '-'; 
			break; // 常规文件
        case S_IFSOCK: 
			str[0] = 's'; 
			break; // 套接字
        default:       
			str[0] = '?'; 
			break; // 未知类型
    }

    // 根据文件权限设置字符串后续字符
    // 设置拥有者权限
    str[1] = (mode & 0400) ? 'r' : '-';
    str[2] = (mode & 0200) ? 'w' : '-';
    str[3] = (mode & 0100) ? 'x' : '-';
    // 设置拥有者组的权限
    str[4] = (mode & 0040) ? 'r' : '-';
    str[5] = (mode & 0020) ? 'w' : '-';
    str[6] = (mode & 0010) ? 'x' : '-';
    // 设置其他人的权限
    str[7] = (mode & 0004) ? 'r' : '-';
    str[8] = (mode & 0002) ? 'w' : '-';
    str[9] = (mode & 0001) ? 'x' : '-';
    str[10] = '\0'; // 确保字符串以 null 结尾
}


/* Usage: 实现ls命令 */
int main(int argc, char* argv[]){
	ARGS_CHECK(argc, 2);


	DIR *dirp = opendir(argv[1]);
	ERROR_CHECK(dirp, NULL, "opendir");


	// 解决stat函数的path参数问题
	int ret = chdir(argv[1]);
	ERROR_CHECK(ret, -1, "chdir");

	struct dirent *pdirent;
	while((pdirent = readdir(dirp)) != NULL){
		struct stat statbuf;

		int ret2 = stat(pdirent->d_name, &statbuf);
		ERROR_CHECK(ret2, -1, "stat");

		// 打印文件信息
		char buf[10] = {0};
		set_type_mode(statbuf.st_mode,buf);
		struct passwd* user = getpwuid(statbuf.st_uid);
		struct group* userg = getgrgid(statbuf.st_gid);
		struct tm *time = localtime(&statbuf.st_mtime);

		//printf("%d %d %d %d %d\n",time->tm_year + 1900,time->tm_mon + 1,time->tm_mday, time->tm_hour,time->tm_min);


		printf("%s\t%lu\t%s\t%s\t%d\t%d月%d日\t%d:%d\t%s\n",
		buf,
		statbuf.st_nlink,
		user->pw_name,
		userg->gr_name,
		statbuf.st_size,
		time->tm_mon,
		time->tm_mday,
		time->tm_hour,
		time->tm_min,
		pdirent->d_name);

	}
	closedir(dirp);

	return 0;
}